<?php
/**
 * Created by PhpStorm.
 * User: kevin
 * Date: 2018/1/3
 * Time: 13:14
 */

namespace app\index\model\pay;
require_once(dirname(__FILE__).'/'."../../extend/wxpay/lib/WxPay.Api.php");
use think\Exception;

class Wxpay extends BasePay{
    /**
     * 配置
     */
    public function config(){
        return [
            //appid
            'appId'=>'wx292e1491eca7a249',
            //appSecret
            'appSecret'=>'7dae8aa84a022ac8e160448f01523345',
            //商户号
            'mchId'=>'1493550662',
            //商户支付密钥
            'key'=>'9JTOvroPhcxaAnosVXkwGtWlilsCkkOR',
            //证书文件路径
            'sslCertPath'=>dirname(__FILE__).'/'."../../extend/wxpay/cert/apiclient_cert.pem",
            'sslKeyPath'=>dirname(__FILE__).'/'."../../extend/wxpay/cert/apiclient_key.pem",
            //代理配置
            'curlProxyHost'=>'0.0.0.0',
            'curlProxyPort'=>0,
            //上报信息
            'reportLevenl'=>1
        ];
    }

    /**
     * 支付
     */
    public function pay($data){
        try{
            //return $this->getUrl()['notifyUrl'];
            $config = $this->config();
            //设置参数
            $input = new \WxPayUnifiedOrder();
            $input->SetBody('挪丹瑞芬');
            $input->SetOut_trade_no($data['order_number']);
            $input->SetProduct_id($data['order_number']);
            $input->SetTotal_fee($data['money']*100);
            $input->SetTrade_type('NATIVE');
            //设置url
            $input->SetNotify_url($this->getUrl()['notifyUrl']);
            //自定义参数
            $input->SetAttach($this->attach($data['user_id'],$data['id'],$data['order_number']));
            $input->SetTime_start(date('YmdHis'));
            $input->SetTime_expire(date('YmdHis', time()+600));

            //下单
            $api = new \WxPayApi($config);
            $result = $api->unifiedOrder($input);
            //dump($result);die;
            $codeUrl = $result['code_url'];
            if($codeUrl){
                return substr(url('Wxpay/qrcode'),0,strlen(url('Wxpay/qrcode'))-5).'?url='.$codeUrl;
            }
        }catch(\Exception $e){
            if($this->debug){
                throw new Exception($e->getMessage());
            }
        }
        return false;
    }

    /**
     * 编码自定义参数
     * $order_id, $user_id, $order_number
     */
    public function attach($user_id,$order_id,$order_number)
    {
        //return base64_encode(json_encode(['user_id'=>1234]));
        return base64_encode(json_encode(['user_id' => $user_id, 'order_id' => $order_id, 'order_number' => $order_number]));
        //return base64_encode(json_encode(['uid'=>$this->uid, 'orderNumber'=>$this->orderNumber, 'method'=>$this->method]));
    }

    /**
     * 解码自定义参数
     * author caowang.
     * date 2018/3/22
     */
    public static function decodeParams($params)
    {
        return json_decode(base64_decode($params), true);
    }
    /**
     * 回调页面
     */
    public function back(){
        return $this->result();
    }

    /**
     * 异步通知
     */
    public function notify($data){
        try{
            //转换数据格式（xml string->array），校验数据
            $data = \WxPayResults::Init($data, $this->config()['key']);
            if($data && $this->verify($data)){
                //微信交易号
                $tradeNo = $data['transaction_id'];
                //处理订单
                if($this->complete($tradeNo)){
                    return 'success';
                }
            }
        }catch(\Exception $e){
            if($this->debug){
                Pay::fileLog('notify:'.$e->getMessage(), 'debug.log');
            }
        }
        return 'fail';
    }

    /**
     * 校验商家、订单数据
     */
    public function verify($data){
        $config = $this->config();
        return ($data['out_trade_no']==$this->orderNumber && $data['total_fee']==100*$this->getMoney() && $data['mch_id']==$config['mchId'] && $data['return_code']=='SUCCESS' && $data['result_code']=='SUCCESS');
    }

    /**
     *
     * 通过跳转获取用户的openid，跳转流程如下：
     * 1、设置自己需要调回的url及其其他参数，跳转到微信服务器https://open.weixin.qq.com/connect/oauth2/authorize
     * 2、微信服务处理完成之后会跳转回用户redirect_uri地址，此时会带上一些参数，如：code
     *
     * @return 用户的openid
     */
    public function GetOpenid()
    {
        //$this->rizhi();
        //通过code获得openid
        if (!isset($_GET['code'])){
            //return 1;
            //触发微信返回code码
            $baseUrl = urlencode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].$_SERVER['QUERY_STRING']);
            //return $baseUrl;
            $url = $this->__CreateOauthUrlForCode($baseUrl);
            //return $url;
            Header("Location: $url");
            exit();
        } else {
            //return 2;
            //获取code码，以获取openid
            $code = $_GET['code'];
            //return $code;
            $openid = $this->getOpenidFromMp($code);
            return $openid;
        }
    }

    /**
     *
     * 构造获取code的url连接
     * @param string $redirectUrl 微信服务器回跳的url，需要url编码
     *
     * @return 返回构造好的url
     */
    public function __CreateOauthUrlForCode($redirectUrl)
    {
        $urlObj["appid"] = 'wx292e1491eca7a249';
        //return $urlObj["appid"];
        $urlObj["redirect_uri"] = "$redirectUrl";
        $urlObj["response_type"] = "code";
        $urlObj["scope"] = "snsapi_base";//snsapi_base
        $urlObj["state"] = "STATE"."#wechat_redirect";
        $bizString = $this->ToUrlParams($urlObj);
        //return $bizString;
        return "https://open.weixin.qq.com/connect/oauth2/authorize?".$bizString;
    }

    /**
     * 格式化参数格式化成url参数
     */
    protected function ToUrlParams($arr)
    {
        $buff = "";

        foreach ($arr as $k => $v)
        {
            if ($k != "sign" && $v != "" && !is_array($v))
            {
                $buff .= $k . "=" . $v . "&";
            }
        }
        $buff = trim($buff, "&");
        return $buff;
    }

    /**
     *
     * 通过code从工作平台获取openid机器access_token
     * @param string $code 微信跳转回来带上的code
     *
     * @return openid
     */
    public function GetOpenidFromMp($code)
    {
        //$path='http://www.importndsf.com/import_nbsm/nbsm_shopping/vendor/WxPayAPI_php_3/lib/WxPay.Config.php';
        //include($path);
        $url = $this->__CreateOauthUrlForOpenid($code);
        //初始化curl
        // return $url;
        $ch = curl_init();
        //设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, 60);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,FALSE);
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        //return WxPayConfig::CURL_PROXY_HOST;
        if(\WxPayConfig::CURL_PROXY_HOST != "0.0.0.0"
            && \WxPayConfig::CURL_PROXY_PORT != 0){
            //return 1;
            curl_setopt($ch,CURLOPT_PROXY, \WxPayConfig::CURL_PROXY_HOST);
            curl_setopt($ch,CURLOPT_PROXYPORT, \WxPayConfig::CURL_PROXY_PORT);
        }
        //return $ch;
        //运行curl，结果以jason形式返回
        $res = curl_exec($ch);
        curl_close($ch);
        //取出openid
        $data = json_decode($res,true);
        //return $res;
        $this->data = $data;
        $openid = $data['openid'];
        return $openid;
    }

    /**
     *
     * 构造获取open和access_toke的url地址
     * @param string $code，微信跳转带回的code
     *
     * @return 请求的url
     */
    private function __CreateOauthUrlForOpenid($code)
    {
        //return 3;
        $urlObj["appid"] = \WxPayConfig::APPID;
        $urlObj["secret"] = \WxPayConfig::APPSECRET;
        $urlObj["code"] = $code;
        $urlObj["grant_type"] = "authorization_code";
        $bizString = $this->ToUrlParams($urlObj);
        return "https://api.weixin.qq.com/sns/oauth2/access_token?".$bizString;
    }
    /**
     *
     * 通过跳转获取用户的openid，跳转流程如下：
     * 1、设置自己需要调回的url及其其他参数，跳转到微信服务器https://open.weixin.qq.com/connect/oauth2/authorize
     * 2、微信服务处理完成之后会跳转回用户redirect_uri地址，此时会带上一些参数，如：code
     *
     * @return 用户的openid
     */
    public function Openid()
    {
        //$this->rizhi();
        //通过code获得openid
        if (!isset($_GET['code'])){
            //return 1;
            //触发微信返回code码
            $baseUrl = urlencode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].$_SERVER['QUERY_STRING']);
            //return $baseUrl;
            $url = $this->__CreateOauthUrlForCode($baseUrl);
            //return $url;
            Header("Location: $url");
            exit();
        } else {
            //return 2;
            //获取code码，以获取openid
            $code = $_GET['code'];
            //return $code;
            $openid = $this->getOpenidFromMp($code);
            return $openid;
        }
    }

}